/*
============================================================================
 Name        : nmsFrame.c
 Author      : Jian
 Version     :
 Copyright   : base on http://ce.sharif.edu/~ahmadinejad/jpeg/
 Description : nmsFrame.c - source file
============================================================================
*/

/* INCLUDE FILES */
#include "nmsFrame.h"
#include "nmsJpegUtil.h"


nmsJpegFrame* nmsJpegFrameReadFrom(HFILE fileHandle)
{
    nmsJpegFrame* frame   = NULL ;
    int len               = 0 ;
    UINT8 byte            = 0 ;
    UINT32 byte2          = 0 ;
    int type              = 0 ;
    nmsJpegFrameComp comp = {0} ;
    int i                 = 0 ;

    frame = (nmsJpegFrame*)nmsJpegMalloc(sizeof(nmsJpegFrame)) ;
    nmsMemSet(frame, 0, sizeof(nmsJpegFrame)) ;

    len = nmsJpegRead2ByteBigEndian(fileHandle) ;

    if (len < 11) {
        nprintf("error: read frame len is too short = %d", len) ;
        goto _error ;
    }

    nmsJpegReadFile(fileHandle, &byte, 1) ;
    if (byte != 8) {
        nprintf("error: read frame precision = %d not support", byte) ;
        goto _error ;
    }

    frame->height = nmsJpegRead2ByteBigEndian(fileHandle) ;
    frame->width  = nmsJpegRead2ByteBigEndian(fileHandle) ;
    if (frame->height == 0 || frame->width == 0) {
        nprintf("error: read frame height = %d or width = %d error", frame->height, frame->width) ;
        goto _error ;
    }

    nmsJpegReadFile(fileHandle, &type, 1) ;
    if (type != __NMS_JPEG_GREY && type != __NMS_JPEG_YUV) {   /* only support grey and YUV */
        nprintf("error: read frame type = %d not support", type) ;
        goto _error ;
    }

    if (len != 8 + 3 * type) {
        nprintf("error: read frame len = %d type = %d not correct", len, type) ;
        goto _error ;
    }

    for (; i < type; i++) {

        nmsJpegReadFile(fileHandle, &comp.id, 1) ;
        if (comp.id <= 0 || comp.id > type || comp.id != (i + 1)) {
            nprintf("error: read frame comp id = %d not correct", byte) ;
            goto _error ;
        }

        nmsJpegReadFile(fileHandle, &byte, 1) ;
        comp.hSample = byte >> 4 ;
        comp.vSample = byte & 0x0F ;
        comp.duCount = comp.hSample * comp.vSample ;

        nmsJpegReadFile(fileHandle, &comp.qtIndex, 1) ;

        frame->comp[comp.id] = comp ;
    }

    frame->cmpCount = type;

    return frame ;

_error :

    nmsJpegFrameFree(frame) ;
    return NULL ;
}

void nmsJpegFrameFree(nmsJpegFrame* frame)
{
    if (frame) {
        nmsJpegFree(frame) ;
    }
}

/* End of File */
